from itertools import count
import random

class Monopoly:
    position = 0
    positions = [0] * 40    
    subsequent_doubles = 0

    GO = 0
    JAIL = 10
    GOTO_JAIL = 30
    COMMUNITY_CHEST = [2, 17, 33]
    CHANCE = [7, 22, 36]
    RAILROAD = [5, 15, 25, 35]
    UTILITY = [12, 28]
    
    def __init__(self, nrSidesPerDice):
        self.nrSidesPerDice = nrSidesPerDice
        
    def is_third_subsequent_double(self, die1, die2):
        if die1 != die2:
            self.subsequent_doubles = 0
            return False

        if 3 == ++self.subsequent_doubles:
            self.subsequent_doubles = 0
            return True

        return False

    def next(self, position, list):
        for l in list:
            if l > position: return l
        
        return list[0]

    def next_railroad(self, position):
        return self.next(position, self.RAILROAD)

    def next_utility(self, position):
        return self.next(position, self.UTILITY)
        
    def community_chest(self, position):
        card = random.randint(1, 16)
        
        if 1 == card: return self.GO
        if 2 == card: return self.JAIL
        return position

    def chance(self, position):
        card = random.randint(1, 16)
        
        if 1 == card: return self.GO
        if 2 == card: return self.JAIL
        if 3 == card: return 11
        if 4 == card: return 24
        if 5 == card: return 39
        if 6 == card: return 5
        if 7 == card: return self.next_railroad(position)
        if 8 == card: return self.next_railroad(position)
        if 9 == card: return self.next_utility(position)
        if 10 == card: return position - 3
        return position            
        
    def advance(self):
        die1 = random.randint(1, self.nrSidesPerDice)
        die2 = random.randint(1, self.nrSidesPerDice)

        self.position = (self.position + die1 + die2) % 40
        
        if self.is_third_subsequent_double(die1, die2):
            self.position = self.JAIL
        
        if self.position == self.GOTO_JAIL:
            self.position = self.JAIL
                    
        if self.position in self.COMMUNITY_CHEST:
            self.positin = self.community_chest(self.position)
            
        if self.position in self.CHANCE:
            self.position = self.chance(self.position)        
        
        self.positions[self.position] += 1
        
    def statistics(self):
        return self.positions      

game = Monopoly(4)

for n in xrange(1, 500000):
    game.advance()

stats = zip(game.statistics(), count())
stats.sort()
stats.reverse()
print stats
        